
#pragma once 
#include "mesh/Mesh.h"
#include <vtkm/cont/DataSet.h>

using NumericVector = ArrayHandle<FloatDefault>;
using VariableName = std::string;

class SystemBase : public vtkm::cont::DataSet
{
public:
	struct WriteVariable :public WorkletMapField
	{
		VTKM_CONT
			WriteVariable(UInt8 eq)
			: _eq(eq)
		{
		}
		using ControlSignature = void(FieldIn solution, FieldOut field);
		using ExecutionSignature = void(_1, _2);

		template<typename SolType, typename FieldType>
		VTKM_EXEC void operator()(const SolType& sol, FieldType& field) const
		{
			field = sol[_eq];
		}

		UInt8 _eq;
	};

public:

	SystemBase(Mesh& mesh) :
		_mesh(mesh)
	{
		this->AddCoordinateSystem(_mesh.GetCoordinate());
		this->SetCellSet(_mesh.GetCellSet());
	}

	virtual UInt8 GetNumberOfVariables() const = 0;

	const Mesh& GetMesh() const { return this->_mesh; }

	virtual void Projection() = 0;


	virtual void Update() = 0;


	virtual void Solve() = 0;

	const NumericVector& GetSolution() const { return this->_solution; }

	virtual void FillField() = 0;

	virtual NumericVector GetSolution(UInt8 id) = 0;
	virtual NumericVector GetSolution(const VariableName& name) = 0;

	void Output()
	{
	
	}

protected:
	Mesh& _mesh;
	NumericVector _solution;
};